package io.github.wanggit.antrpc.console.zookeeper;

import io.github.wanggit.antrpc.commons.bean.ConfigItemData;
import io.github.wanggit.antrpc.commons.constants.ConstantValues;
import io.github.wanggit.antrpc.console.web.vo.ConfigVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Component
@Slf4j
public class DefaultConfigContainer implements IConfigContainer {

    private final ConcurrentHashMap<String, ConfigVO> localConfigVOs = new ConcurrentHashMap<>();

    @Override
    public void saveOrUpdate(ConfigVO configVO) {
        localConfigVOs.put(configVO.getFullPath(), configVO);
    }

    @Override
    public void delete(ConfigVO configVO) {
        localConfigVOs.remove(configVO.getFullPath());
    }

    @Override
    public List<String> findAllEnvs(String pattern) {
        return localConfigVOs.values().stream()
                .map(ConfigVO::getEnv)
                .distinct()
                .filter(
                        it ->
                                null != it
                                        && (null == pattern
                                                || it.toLowerCase()
                                                        .contains(pattern.toLowerCase())))
                .sorted()
                .collect(Collectors.toList());
    }

    @Override
    public List<ConfigVO> find(String pattern) {
        Collection<ConfigVO> configVOS = localConfigVOs.values();
        return configVOS.stream()
                .filter(it -> it.getSpaceName().toLowerCase().contains(pattern.toLowerCase()))
                .sorted(Comparator.comparing(ConfigVO::getSpaceName))
                .collect(Collectors.toList());
    }

    @Override
    public List<String> findAllSpaces(String keyword, String envName) {
        return localConfigVOs.values().stream()
                .filter(it -> Objects.equals(envName, it.getEnv()))
                .map(ConfigVO::getSpaceName)
                .distinct()
                .filter(
                        it ->
                                null != it
                                        && (null == keyword
                                                || it.toLowerCase()
                                                        .contains(keyword.toLowerCase())))
                .sorted()
                .collect(Collectors.toList());
    }

    @Override
    public List<ConfigVO> findAllKeys(String keyword, String envName, String spaceName) {
        return localConfigVOs.values().stream()
                .filter(
                        it ->
                                null != it.getConfigItemData()
                                        && Objects.equals(it.getEnv(), envName)
                                        && Objects.equals(it.getSpaceName(), spaceName)
                                        && (null == keyword
                                                || it.getConfigItemData()
                                                        .getKey()
                                                        .toLowerCase()
                                                        .contains(keyword.toLowerCase())))
                .sorted(
                        (o1, o2) ->
                                o1.getConfigItemData()
                                        .getKey()
                                        .compareToIgnoreCase(o2.getConfigItemData().getKey()))
                .collect(Collectors.toList());
    }

    @Override
    public ConfigItemData findConfigItemData(String envName, String spaceName, String key) {
        String fullPath =
                "/"
                        + ConstantValues.ZK_ROOT_CONFIG_NAME
                        + "/"
                        + envName
                        + "/"
                        + spaceName
                        + "/"
                        + key;
        ConfigVO configVO = localConfigVOs.get(fullPath);
        if (null == configVO) {
            return null;
        }
        return configVO.getConfigItemData();
    }

    @Override
    public void saveOrUpdateEnv(ConfigVO configVO) {
        localConfigVOs.put(configVO.getFullPath(), configVO);
    }

    @Override
    public void saveOrUpdateSpace(ConfigVO configVO) {
        localConfigVOs.put(configVO.getFullPath(), configVO);
    }

    @Override
    public void deleteEnv(ConfigVO configVO) {
        localConfigVOs.remove(configVO.getFullPath());
    }

    @Override
    public void deleteSpace(ConfigVO configVO) {
        localConfigVOs.remove(configVO.getFullPath());
    }

    @Override
    public List<ConfigVO> configFuzzyQuery(String pattern) {
        return localConfigVOs.values().stream()
                .filter(
                        it ->
                                null != it.getConfigItemData()
                                        && (null == pattern
                                                || it.getFullPath()
                                                        .toLowerCase()
                                                        .contains(pattern.toLowerCase())
                                                || it.getConfigItemData()
                                                        .getValue()
                                                        .toLowerCase()
                                                        .contains(pattern.toLowerCase())))
                .sorted((o1, o2) -> o1.getFullPath().compareToIgnoreCase(o2.getFullPath()))
                .collect(Collectors.toList());
    }
}
